package com.avalieme.logica;
import java.util.ArrayList;
import java.util.List;

import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Tweet;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import weka.classifiers.bayes.NaiveBayesUpdateable;
import weka.core.SerializationHelper;

import com.avalieme.classificadores.Classificador;
import com.avalieme.classificadores.ClassificadorException;
import com.avalieme.util.Constantes;

public class AvalieMe {

	final Integer QUANTIDADE_MAXIMA = 100;
	private List<Tweet> opinativos = new ArrayList<Tweet>();
	private List<Tweet> positivos = new ArrayList<Tweet>();
	private List<Tweet> negativos = new ArrayList<Tweet>();
	private List<Tweet> resultado = new ArrayList<Tweet>();
	private Classificador classificador;
	private Integer totalTweets;
	private Integer totalPositivo = 0;
	private Integer totalNegativo = 0;
	private String hashtag;
	
	public AvalieMe(String hashtag) {
		this.hashtag = hashtag;
	}

	public List<Tweet> avaliar() {
		if ((!hashtag.startsWith("#"))) {
			System.err.println("Erro: Deve-se digitar uma hashtag de twitter."
					+ " Exemplo: #inteligenciaartificial");
			return null;
		}
		try {
			classificador = (Classificador) SerializationHelper
					.read(Constantes.getModelo());
		} catch (Exception e) {
			classificador = new Classificador(new NaiveBayesUpdateable(), Constantes.getModelo(), false);
		}

		try {
			classificador.carregar();
		} catch (ClassificadorException e1) {
			e1.printStackTrace();
		}
		//String hashtag = args[0];
	    
		Twitter twitter = new TwitterFactory().getInstance();
		Query query = new Query(hashtag);
		query.setRpp(QUANTIDADE_MAXIMA);
		String classe = Constantes.CLASSE_NEUTRO;
		try {
			QueryResult result = twitter.search(query);
			resultado = result.getTweets();
			for (Tweet tweet : resultado) {
				// classificar em neutro ou opinativo
				// os opinativos sao colocados na lista de opinativos
				try {
					classe = classificador.classificar(tweet.getText());
				} catch (ClassificadorException e) {
					e.printStackTrace();
				}
				if (classe.equals("opinativo")) {
					opinativos.add(tweet);
				}

				System.out.println(tweet.getFromUser() + ": " + tweet.getText());
			}
			// System.out.println(resultado.size());

			// classificador = new TweetClassifier(new J48(),
			// getModelArvorePN());
			
			try {
				classificador = (Classificador) SerializationHelper.read(Constantes.getModeloPN());
			} catch (Exception e) {
				classificador = new Classificador(new NaiveBayesUpdateable(), Constantes.getModeloPN(), true);
			}
			
			try {
				System.out.println("Aguarde! Carregando o classificador...");
				classificador.carregar();
			} catch (ClassificadorException e1) {
				e1.printStackTrace();
			}
			
			for (Tweet tweet : opinativos) {
				try {
					classe = classificador.classificar(tweet.getText());
				} catch (ClassificadorException e) {
					e.printStackTrace();
				}
				if (classe.equals("positivo")) {
					System.out.println("Tweet Positivo: "+tweet.getText());
					positivos.add(tweet);
					totalPositivo++;
				} else {
					System.out.println("Tweet Negativo: "+tweet.getText());
					negativos.add(tweet);
					totalNegativo++;
				}
			}
			

		} catch (TwitterException e) {
			System.err.println("Erro: Tente novamente :D");
			return null;
		}
		Integer totalNeutro = resultado.size() - opinativos.size();
		System.out.println("Hashtag pesquisada: " + hashtag);
		System.out.println("Total de tweets encontrados: " + resultado.size());
		System.out.println("Total de tweets opinativos: " + opinativos.size());
		System.out.println("Total de tweets neutros: " + totalNeutro);
		System.out.println("Total de positivos: "+totalPositivo);
		System.out.println("Total de negativo: "+totalNegativo);
		System.out.println("Opinativos: ");
		for(Tweet tweet : opinativos) {
			System.out.println(tweet.getText());
		}
		return opinativos;
	}
	
	public Integer getTotal() {
		return resultado.size();
	}
	
	public List<Tweet> getPositivos() {
		return positivos;
	}
	
	public List<Tweet> getNegativos() {
		return negativos;
	}
	
	public Integer getTotalPositivo() {
		return totalPositivo;
	}
	public Integer getTotalNegativo() {
		return totalNegativo;
	}
}
